package vn.edu.saigontech.ncms.web.offering;

import java.util.Collection;
import java.util.Date;

import vn.edu.saigontech.ncms.model.enumeration.TeacherType;
import vn.edu.saigontech.ncms.model.info.NextOffering;
import vn.edu.saigontech.ncms.model.info.Offering;
import vn.edu.saigontech.ncms.model.program.Level;
import vn.edu.saigontech.ncms.model.program.Program;
import vn.edu.saigontech.ncms.service.LevelService;
import vn.edu.saigontech.ncms.service.LocationService;
import vn.edu.saigontech.ncms.service.NextOfferingService;
import vn.edu.saigontech.ncms.service.OfferingService;
import vn.edu.saigontech.ncms.service.ProgramService;
import vn.edu.saigontech.ncms.service.RoomService;
import vn.edu.saigontech.ncms.service.ShiftService;
import vn.edu.saigontech.ncms.service.TeacherService;
import vn.edu.saigontech.ncms.util.Checker;
import vn.edu.saigontech.ncms.util.DateUtil;
import vn.edu.saigontech.ncms.web.BaseAction;

@SuppressWarnings("serial")
public class OfferingAction extends BaseAction {
	
	private Long id;
	private String name;
	private Long programId;
	private Long levelId;
	private Long roomId;
	private Long shiftId;
	private String startDate;
	private String endDate;
	private String fromDate;
	private String toDate;
	private String midtermWrittenDate;
	private String finalSpokenDate;
	private String finalWrittenDate;
	private String cambridgeSpokenDate;
	private String cambridgeWrittenDate;
	private String issueDate;
	private boolean cancel;
	
	private Long monTeacherId;
	private Long tueTeacherId;
	private Long wedTeacherId;
	private Long thuTeacherId;
	private Long friTeacherId;
	private Long satTeacherId;
	private Long sunTeacherId;
	
	private Long taMonTeacherId;
	private Long taTueTeacherId;
	private Long taWedTeacherId;
	private Long taThuTeacherId;
	private Long taFriTeacherId;
	private Long taSatTeacherId;
	private Long taSunTeacherId;
	
	private String comment;
	
	public String showAdd() {
		REQUEST().setAttribute("programs", ProgramService.INSTANCE.findAll());
		REQUEST().setAttribute("locations", LocationService.INSTANCE.findAllAreActive());
		REQUEST().setAttribute("teachers", TeacherService.INSTANCE.findActiveByTeacherType(TeacherType.INSTRUCTOR));
		REQUEST().setAttribute("shifts", ShiftService.INSTANCE.findAll());
		REQUEST().setAttribute("chosenlevel", LevelService.INSTANCE.findById(this.levelId));
		return SUCCESS;
	}
		
	public String add() {
		Offering offering = new Offering();
		offering.setName(this.name);
		Level level = LevelService.INSTANCE.findById(levelId);
		offering.setLevel(level);
		offering.setRoom(RoomService.INSTANCE.findById(roomId));
		offering.setShift(ShiftService.INSTANCE.findById(shiftId));
		offering.setCancel(false);
		
		Program program = level.getProgram();
		offering.setFinalGradeDetail(program.getFinalGradeDetail());
		offering.setMidtermGradeDetail(program.getMidtermGradeDetail());
		offering.setCambridgeGradeDetail(program.getCambridgeGradeDetail());
		
		offering.setStartDate(DateUtil.fromString(this.startDate, this.i18n("format.date")));
		offering.setEndDate(DateUtil.fromString(this.endDate, this.i18n("format.date")));
		
		offering.setMidtermWrittenDate(DateUtil.fromString(this.midtermWrittenDate, this.i18n("format.date")));
		offering.setFinalSpokenDate(DateUtil.fromString(this.finalSpokenDate, this.i18n("format.date")));
		offering.setFinalWrittenDate(DateUtil.fromString(this.finalWrittenDate, this.i18n("format.date")));
		
		offering.setIssueDate(DateUtil.fromString(this.issueDate, this.i18n("format.date")));
		offering.setCambridgeSpokenDate(DateUtil.fromString(this.cambridgeSpokenDate, this.i18n("format.date")));
		offering.setCambridgeWrittenDate(DateUtil.fromString(this.cambridgeWrittenDate, this.i18n("format.date")));
		
		offering.setMonTeacher(TeacherService.INSTANCE.findById(monTeacherId));
		offering.setTueTeacher(TeacherService.INSTANCE.findById(tueTeacherId));
		offering.setWedTeacher(TeacherService.INSTANCE.findById(wedTeacherId));
		offering.setThuTeacher(TeacherService.INSTANCE.findById(thuTeacherId));
		offering.setFriTeacher(TeacherService.INSTANCE.findById(friTeacherId));
		offering.setSatTeacher(TeacherService.INSTANCE.findById(satTeacherId));
		offering.setSunTeacher(TeacherService.INSTANCE.findById(sunTeacherId));
		
		offering.setMonTATeacher(TeacherService.INSTANCE.findById(taMonTeacherId));
		offering.setTueTATeacher(TeacherService.INSTANCE.findById(taTueTeacherId));
		offering.setWedTATeacher(TeacherService.INSTANCE.findById(taWedTeacherId));
		offering.setThuTATeacher(TeacherService.INSTANCE.findById(taThuTeacherId));
		offering.setFriTATeacher(TeacherService.INSTANCE.findById(taFriTeacherId));
		offering.setSatTATeacher(TeacherService.INSTANCE.findById(taSatTeacherId));
		offering.setSunTATeacher(TeacherService.INSTANCE.findById(taSunTeacherId));
		
		offering.setComment(this.comment);
		offering = OfferingService.INSTANCE.persist(offering);
		offering.setNextOffering(updateNextOffering(offering));
		this.id = offering.getId();
		this.addLoggingDetail(BaseAction.ADD, "logging.offering.add", offering.getName());
		return SUCCESS;
	}
	
	private NextOffering updateNextOffering(Offering offering) {
		NextOffering ret = new NextOffering();
		Date startDate = DateUtil.addDay(offering.getEndDate(), 10);
		int acc = offering.getLevel().getWeeks() * 7 - 3;
		Date endDate = DateUtil.addDay(startDate, acc);
		ret.setLevel(LevelService.INSTANCE.findNextLevel(offering.getLevel()));
		ret.setStartDate(startDate);
		ret.setEndDate(endDate);
		ret.setShift(offering.getShift());
		ret = NextOfferingService.INSTANCE.persist(ret);
		return ret;
	}
	
	public String info() {
		Offering offering = OfferingService.INSTANCE.findById(this.id);
		
		REQUEST().setAttribute("program", offering.getLevel().getProgram());
		REQUEST().setAttribute("locations", LocationService.INSTANCE.findAllAreActive());
		REQUEST().setAttribute("teachers", TeacherService.INSTANCE.findActiveByTeacherType(TeacherType.INSTRUCTOR));
		REQUEST().setAttribute("shifts", ShiftService.INSTANCE.findAll());
		REQUEST().setAttribute("offering", offering);
		REQUEST().setAttribute("nextOffering", offering.getNextOffering());
		return SUCCESS;
	}
	
	public String edit() {	
		Offering offering = OfferingService.INSTANCE.findById(this.id);
		offering.setName(name);
		offering.setLevel(LevelService.INSTANCE.findById(levelId));
		offering.setRoom(RoomService.INSTANCE.findById(roomId));
		offering.setShift(ShiftService.INSTANCE.findById(shiftId));
		offering.setCancel(cancel);
		
		offering.setStartDate(DateUtil.fromString(this.startDate, this.i18n("format.date")));
		offering.setEndDate(DateUtil.fromString(this.endDate, this.i18n("format.date")));
		
		offering.setMidtermWrittenDate(DateUtil.fromString(this.midtermWrittenDate, this.i18n("format.date")));
		offering.setFinalSpokenDate(DateUtil.fromString(this.finalSpokenDate, this.i18n("format.date")));
		offering.setFinalWrittenDate(DateUtil.fromString(this.finalWrittenDate, this.i18n("format.date")));
		offering.setIssueDate(DateUtil.fromString(this.issueDate, this.i18n("format.date")));
		
		offering.setCambridgeSpokenDate(DateUtil.fromString(this.cambridgeSpokenDate, this.i18n("format.date")));
		offering.setCambridgeWrittenDate(DateUtil.fromString(this.cambridgeWrittenDate, this.i18n("format.date")));
		
		offering.setMonTeacher(TeacherService.INSTANCE.findById(monTeacherId));
		offering.setTueTeacher(TeacherService.INSTANCE.findById(tueTeacherId));
		offering.setWedTeacher(TeacherService.INSTANCE.findById(wedTeacherId));
		offering.setThuTeacher(TeacherService.INSTANCE.findById(thuTeacherId));
		offering.setFriTeacher(TeacherService.INSTANCE.findById(friTeacherId));
		offering.setSatTeacher(TeacherService.INSTANCE.findById(satTeacherId));
		offering.setSunTeacher(TeacherService.INSTANCE.findById(sunTeacherId));
		
		offering.setMonTATeacher(TeacherService.INSTANCE.findById(taMonTeacherId));
		offering.setTueTATeacher(TeacherService.INSTANCE.findById(taTueTeacherId));
		offering.setWedTATeacher(TeacherService.INSTANCE.findById(taWedTeacherId));
		offering.setThuTATeacher(TeacherService.INSTANCE.findById(taThuTeacherId));
		offering.setFriTATeacher(TeacherService.INSTANCE.findById(taFriTeacherId));
		offering.setSatTATeacher(TeacherService.INSTANCE.findById(taSatTeacherId));
		offering.setSunTATeacher(TeacherService.INSTANCE.findById(taSunTeacherId));
		
		offering.setComment(comment);
		offering = OfferingService.INSTANCE.persist(offering);
		this.addLoggingDetail(BaseAction.EDIT, "logging.offering.edit", this.name);
		return SUCCESS;
	}
	
	public String delete() {
		Offering offering = OfferingService.INSTANCE.findById(this.id);
		if(OfferingService.INSTANCE.deleteById(this.id)) {
			this.setKeyMessage("confirm.deleteSuccessfully", "offering");
		}
		else {
			this.setKeyMessage("confirm.deleteUnsuccessfully", "offering");
		}
		this.addLoggingDetail(BaseAction.DELETE, "logging.offering.delete", offering.getName());
		return SUCCESS;
	}
	
	public String showSearchByTestDate() {
		this.fromDate = DateUtil.toString(DateUtil.startOfMonth(DateUtil.newDate()), this.i18n("format.date"));
		this.toDate = DateUtil.toString(DateUtil.endOfMonth(DateUtil.newDate()), this.i18n("format.date"));
		return SUCCESS;
	}
	
	public String searchByTestDate() {
		Date fromDate = Checker.isDate(this.fromDate, this.i18n("format.date"))? DateUtil.fromString(this.fromDate, this.i18n("format.date")) : null;
		Date toDate = Checker.isDate(this.toDate, this.i18n("format.date"))? DateUtil.fromString(this.toDate, this.i18n("format.date")) : null;
		Collection<Offering> offerings = OfferingService.INSTANCE.findByTestDate(fromDate, toDate);
		
		REQUEST().setAttribute("offerings", offerings);
		this.addLoggingDetail(BaseAction.SEARCH, "logging.offering.search.byTestDate");
		return SUCCESS;
	}
	
	public String showSearch() {
		REQUEST().setAttribute("programs", ProgramService.INSTANCE.findAll());
		REQUEST().setAttribute("locations", LocationService.INSTANCE.findAllAreActive());
		REQUEST().setAttribute("teachers", TeacherService.INSTANCE.findActiveByTeacherType(TeacherType.INSTRUCTOR));
		REQUEST().setAttribute("tas", TeacherService.INSTANCE.findActiveByTeacherType(TeacherType.TA));
		REQUEST().setAttribute("shifts", ShiftService.INSTANCE.findAll());
		return SUCCESS;
	}
	
	public String search() {
		Date fromDate = Checker.isDate(this.fromDate, this.i18n("format.date"))? DateUtil.fromString(this.fromDate, this.i18n("format.date")) : null;
		Date toDate = Checker.isDate(this.toDate, this.i18n("format.date"))? DateUtil.fromString(this.toDate, this.i18n("format.date")) : null;
		Collection<Offering> offerings = OfferingService.INSTANCE.find(
				this.name, this.programId, this.levelId, this.roomId, this.shiftId,
				DateUtil.fromString(this.startDate, this.i18n("format.date")), 
				DateUtil.fromString(this.endDate, this.i18n("format.date")), 
				fromDate, toDate,
				DateUtil.fromString(this.midtermWrittenDate, this.i18n("format.date")),
				DateUtil.fromString(this.finalSpokenDate, this.i18n("format.date")),
				DateUtil.fromString(this.finalWrittenDate, this.i18n("format.date")),
				DateUtil.fromString(this.issueDate, this.i18n("format.date")),
				DateUtil.fromString(this.cambridgeSpokenDate, this.i18n("format.date")),
				DateUtil.fromString(this.cambridgeWrittenDate, this.i18n("format.date")),
				this.monTeacherId, this.tueTeacherId, this.wedTeacherId, 
				this.thuTeacherId, this.friTeacherId, this.satTeacherId, 
				this.sunTeacherId, this.comment
		);
		REQUEST().setAttribute("offerings", offerings);
		this.addLoggingDetail(BaseAction.SEARCH, "logging.offering.search");
		return SUCCESS;
	}
	
	public String requestName() throws Exception {
		StringBuilder builder = new StringBuilder();
		builder.append("<items>");
		if(!Checker.isEmpty(this.name)) {
			for(Offering offering : OfferingService.INSTANCE.findByNameStartWith(this.name)) {
				String startDate = DateUtil.toString(offering.getStartDate(), this.i18n("format.date"));
				String endDate = DateUtil.toString(offering.getEndDate(), this.i18n("format.date"));
				builder.append("<item>").append(offering.getName()).append(" | ");
				builder.append(startDate).append("-").append(endDate).append(" | ");
				builder.append(offering.getNumberOfStudents()).append(" #").append(offering.getId()).append("</item>");
			}
		}
		builder.append("</items>");
		RESPONSE().setContentType("text/xml");
		RESPONSE().getOutputStream().print(builder.toString());
		return NONE;
	}
	
	public String showAllOpening() {
		REQUEST().setAttribute("offerings", OfferingService.INSTANCE.findAllOpening());
		return SUCCESS;
	}

	public String showHistory() {
		return this.info();
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public String getEndDate() {
		return endDate;
	}

	public void setEndDate(String endDate) {
		this.endDate = endDate;
	}

	public Long getFriTeacherId() {
		return friTeacherId;
	}

	public void setFriTeacherId(Long friTeacherId) {
		this.friTeacherId = friTeacherId;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Long getMonTeacherId() {
		return monTeacherId;
	}

	public void setMonTeacherId(Long monTeacherId) {
		this.monTeacherId = monTeacherId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Long getSatTeacherId() {
		return satTeacherId;
	}

	public void setSatTeacherId(Long satTeacherId) {
		this.satTeacherId = satTeacherId;
	}

	public Long getShiftId() {
		return shiftId;
	}

	public void setShiftId(Long shiftId) {
		this.shiftId = shiftId;
	}

	public String getStartDate() {
		return startDate;
	}

	public void setStartDate(String startDate) {
		this.startDate = startDate;
	}

	public Long getSunTeacherId() {
		return sunTeacherId;
	}

	public void setSunTeacherId(Long sunTeacherId) {
		this.sunTeacherId = sunTeacherId;
	}

	public Long getThuTeacherId() {
		return thuTeacherId;
	}

	public void setThuTeacherId(Long thuTeacherId) {
		this.thuTeacherId = thuTeacherId;
	}

	public Long getTueTeacherId() {
		return tueTeacherId;
	}

	public void setTueTeacherId(Long tueTeacherId) {
		this.tueTeacherId = tueTeacherId;
	}

	public Long getWedTeacherId() {
		return wedTeacherId;
	}

	public void setWedTeacherId(Long wedTeacherId) {
		this.wedTeacherId = wedTeacherId;
	}

	public Long getLevelId() {
		return levelId;
	}

	public void setLevelId(Long levelId) {
		this.levelId = levelId;
	}

	public String getMidtermWrittenDate() {
		return midtermWrittenDate;
	}

	public void setMidtermWrittenDate(String midtermWrittenDate) {
		this.midtermWrittenDate = midtermWrittenDate;
	}

	public String getFinalSpokenDate() {
		return finalSpokenDate;
	}

	public void setFinalSpokenDate(String finalSpokenDate) {
		this.finalSpokenDate = finalSpokenDate;
	}

	public String getFinalWrittenDate() {
		return finalWrittenDate;
	}

	public void setFinalWrittenDate(String finalWrittenDate) {
		this.finalWrittenDate = finalWrittenDate;
	}

	public String getIssueDate() {
		return issueDate;
	}

	public void setIssueDate(String issueDate) {
		this.issueDate = issueDate;
	}

	public Long getRoomId() {
		return roomId;
	}

	public void setRoomId(Long roomId) {
		this.roomId = roomId;
	}

	public String getFromDate() {
		return fromDate;
	}

	public void setFromDate(String fromDate) {
		this.fromDate = fromDate;
	}

	public String getToDate() {
		return toDate;
	}

	public void setToDate(String toDate) {
		this.toDate = toDate;
	}

	public Long getProgramId() {
		return programId;
	}

	public void setProgramId(Long programId) {
		this.programId = programId;
	}

	public Long getTaMonTeacherId() {
		return taMonTeacherId;
	}

	public void setTaMonTeacherId(Long taMonTeacherId) {
		this.taMonTeacherId = taMonTeacherId;
	}

	public Long getTaTueTeacherId() {
		return taTueTeacherId;
	}

	public void setTaTtueTeacherId(Long taTueTeacherId) {
		this.taTueTeacherId = taTueTeacherId;
	}

	public Long getTaWedTeacherId() {
		return taWedTeacherId;
	}

	public void setTaWedTeacherId(Long taWedTeacherId) {
		this.taWedTeacherId = taWedTeacherId;
	}

	public Long getTaThuTeacherId() {
		return taThuTeacherId;
	}

	public void setTaThuTeacherId(Long taThuTeacherId) {
		this.taThuTeacherId = taThuTeacherId;
	}

	public Long getTaFriTeacherId() {
		return taFriTeacherId;
	}

	public void setTaFriTeacherId(Long taFriTeacherId) {
		this.taFriTeacherId = taFriTeacherId;
	}

	public Long getTaSatTeacherId() {
		return taSatTeacherId;
	}

	public void setTaSatTeacherId(Long taSatTeacherId) {
		this.taSatTeacherId = taSatTeacherId;
	}

	public Long getTaSunTeacherId() {
		return taSunTeacherId;
	}

	public void setTaSunTeacherId(Long taSunTeacherId) {
		this.taSunTeacherId = taSunTeacherId;
	}

	public void setTaTueTeacherId(Long taTueTeacherId) {
		this.taTueTeacherId = taTueTeacherId;
	}

	public String getCambridgeSpokenDate() {
		return cambridgeSpokenDate;
	}

	public void setCambridgeSpokenDate(String cambridgeSpokenDate) {
		this.cambridgeSpokenDate = cambridgeSpokenDate;
	}

	public String getCambridgeWrittenDate() {
		return cambridgeWrittenDate;
	}

	public void setCambridgeWrittenDate(String cambridgeWrittenDate) {
		this.cambridgeWrittenDate = cambridgeWrittenDate;
	}

	public Boolean isCancel() {
		return cancel;
	}

	public void setCancel(Boolean cancel) {
		this.cancel = cancel;
	}	
}